#ifndef __COMMON_TYPES_H__
#define __COMMON_TYPES_H__

#include "common/vector3.h"
#include "common/common_defs.h"
#include <stdint.h>

////////////////////////////////////////////////////////////////////////////////

// sizeof == 32 bytes, 1/4 cache line
struct ForceInfo {
    float P1;
    float P2;
    float Sigma;
    float Eps;
    char pTp;
    int8_t reserved[3];
    int32_t reserved2[3];
};
STATIC_ASSERT(sizeof(ForceInfo) == 32);

// 0xc80 bytes, 25 cache lines
struct ForcesArray {
    ForceInfo array[MAX_FORCE_INDEX][MAX_FORCE_INDEX];
} ALIGNED_FOR_DMA;
STATIC_ASSERT(sizeof(ForcesArray) == 3200);

// sizeof == 128 bytes, full cache line
struct SpeInitData {
    unsigned long long incomingDataPtr[SHIFTS_COUNT];
    unsigned long long outgoingDataPtr[SHIFTS_COUNT];
    unsigned long long forcesInfoPtr;
    uint32_t packetCount;
    float tau;
} ALIGNED_FOR_DMA;
STATIC_ASSERT(sizeof(SpeInitData) == 128);

////////////////////////////////////////////////////////////////////////////////

// sizeof == 64 bytes, half cache line
struct ParticleData {
    Vector3 pos;
    float mass;
    int32_t componentId;
    int32_t moleculaId;
    int32_t reserved[9];
};
STATIC_ASSERT(sizeof(ParticleData) == 64);

class Component;
struct Cell {
    Component* inCell[MAX_PARTICLES];

    int curIn;
    int stIn;
    bool o_f;
};

////////////////////////////////////////////////////////////////////////////////

// sizeof == 128 bytes, full cache line
struct IncomingDataHeader {
    unsigned long long nextIncomingDataPtr[SHIFTS_COUNT];
    unsigned long long nextOutgoingDataPtr[SHIFTS_COUNT];
    uint32_t particlesCount;
    int32_t reserved[3];
};
STATIC_ASSERT(sizeof(IncomingDataHeader) == 128);

// sizeof == 16K bytes, max DMA transfer size
struct IncomingDataPacket {
    IncomingDataHeader header;
    ParticleData data[MAX_PARTICLES];
} ALIGNED_FOR_DMA;
STATIC_ASSERT(sizeof(IncomingDataPacket) == 16*1024);

// sizeof == 32 bytes, 1/4 cache line
struct OutgoingDataHeader {
    uint32_t accelsCount;
    int32_t reserved[7];
};
STATIC_ASSERT(sizeof(OutgoingDataHeader) == 32);

// sizeof == 4K bytes, 1/4 max DMA transfer size
struct OutgoingDataPacket {
    OutgoingDataHeader header;
    Vector3 accels[MAX_PARTICLES];
} ALIGNED_FOR_DMA;
STATIC_ASSERT(sizeof(OutgoingDataPacket) == 4*1024);

////////////////////////////////////////////////////////////////////////////////

#endif // __COMMON_TYPES_H__
